#ifndef REQUESTHANDLE_H
#define REQUESTHANDLE_H
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QList>
#include <QWaitCondition>
#include "type.h"
#include "nodearray.h"
#include "nodearraycache.h"
class Node;
class QString;
class QEvent;
class FileArray;
class QTreeWidgetItem;
class ErrorReport;
class ProgressReport;
class ErrorHandleResult;
class CancelCopyResult;
class CopyErrorResult;
class WatchThread:public QThread
{
	friend class CopyThread;
	friend class RequestHandle;
private:
	WatchThread(RequestHandle* req):parent(req),is_retry(0),
	is_cancel_copy(false),is_del_file(false),is_cancel_other(false),is_overwrite(false){}
	void run();
	void handleErrorReport();
	void handleProgressReport();
	QWaitCondition wait_con; 
	RequestHandle* parent;
	uint32 is_retry; 
	bool is_cancel_copy;
	bool is_del_file;
	bool is_cancel_other;
	bool is_overwrite;
};
class CopyThread:public QThread
{
	friend class RequestHandle;
private:
	CopyThread(RequestHandle* req):files(),is_finished(true),is_stop(false),parent(req),watch_thread(req){}
	void run();
	void watchStart();
	void watchEnd();
	QList<ParaForCopyFile> files;
	bool is_finished;
	bool is_stop;
	uint32 curr_index;
	QMutex lock_for_files; 
	RequestHandle* parent;
	WatchThread watch_thread;
};
class RequestHandle:public QObject
{
	Q_OBJECT
public:
	RequestHandle(uint32 cache_size):cache(cache_size),copy_thread(this){}
	void cancelCopy();
	bool isCopying(){return copy_thread.isRunning();}
private slots:
	void needNodeArray(const Node& dir,uint32 flag);
	void needNodeArray(const QString& path,uint32 flag);
	void needToCopyFile(QList<QTreeWidgetItem*>& files,const FsIndex& fs_index,const QString& from_path,const QString& to_path);
	void receiveErrorResult(const ErrorHandleResult& re);
signals:
	void sendNodeArray(const Node& dir,const NodeArray* node_array,uint32 flag) const;
	void copyStart(const QString& from_path,const QString& to_path,uint32 file_type);
	void allCopyStart();
	void allCopyEnd();
	void copyProgress(const ProgressReport& pr);
	void error(const ErrorReport&,uint32 sender);
private:
	const NodeArray* getNewNodeArrayFor(const Node& dir) const;
	const NodeArray* getNewNodeArrayFor(const QString& path) const;
	bool event(QEvent* event_);
	void deleteDir(const QString& path);
	void deleteCopyedFiles();
	void handleCancelCopyResult(const CancelCopyResult& re);
	void handleWriteErrorResult(const CopyErrorResult& re);
	void handelCreateErrorResult(const ErrorHandleResult& re);
	NodeArrayCache cache;
	CopyThread copy_thread;
};
#endif